use axum::Json;
use mongodb::{bson::{doc, Bson }, gridfs::{ FilesCollectionDocument, GridFsBucket }, options::GridFsBucketOptions };
use serde_json::{json, Value};

use crate::{chrono::date_format_from_millis, code, mdb::{self, get_object_id_str} };

// 查找文件，获取文件信息
pub async fn get_info_(objectid:Bson, bucket:GridFsBucket) -> Result<FilesCollectionDocument, Json<Value>>{
    if let Some(f) = get_info_op_(objectid.to_owned(), bucket).await? {
        Ok(f)
    }else{
        Err(code::sys_(objectid.as_str().unwrap_or_default().to_string() + "文件不存在，请先上传文件！"))
    }
}
pub async fn get_info_op_(objectid:Bson, bucket:GridFsBucket) -> Result<Option<FilesCollectionDocument>, Json<Value>>{
    let rs = bucket.find(doc!{"_id":objectid.to_owned()}).await;
    match rs {
        Ok(mut d) => {
            match d.advance().await {
                Ok(b) => {
                    if b {
                        let rs = d.deserialize_current();
                        match rs {
                            Ok(f) => Ok( Some(f) ),
                            Err(e) => Err(code::sys_(e.to_string()))
                        }
                    }else{
                        Ok(None)
                    }
                },
                Err(e) => Err(code::sys_(e.to_string()))
            }
        },
        Err(e) => Err(code::sys_(e.to_string()))
    }
}
pub async fn get_info(objectid:&str, bucket_name:&str) -> Result<FilesCollectionDocument, Json<Value>>{
    let conn = mdb::connect().await?;
    let options = GridFsBucketOptions::builder().bucket_name(bucket_name.to_owned()).build();
    let bucket = conn.gridfs_bucket(options);
    Ok(get_info_(mdb::to_object_id(objectid), bucket).await?)
}
// 自定义信息输出 json
pub async fn get_info_json_(objectid:Bson, bucket:GridFsBucket) -> Result<Option<Value>, Json<Value>>{
    if let Some(f) = get_info_op_(objectid, bucket).await? {
        let meta = f.metadata;
        let mut bucket_name:String = String::new();
        let mut file_type = String::new();
        let mut classify = String::new();
        if let Some(f) = meta.to_owned() { 
            bucket_name = f.get_str("bucket").unwrap_or(&"").to_owned();
            file_type = f.get_str("type").unwrap_or(&"").to_owned();
            classify = f.get_str("classify").unwrap_or(&"").to_owned();
         }
       
        let rs = json!({
            "id": get_object_id_str(&f.id),
            "filename": f.filename,
            // "metadata": meta.to_owned(),
            "bucket": bucket_name,
            "type": file_type,
            "classify": classify,
            "size": f.length,
            "size_kb": format!("{}KB", f.length/1024 ),
            "size_mb": format!("{}MB", f.length/1048576 ),
            "chunk_size": f.chunk_size_bytes,
            "chunk_kb": format!("{}KB", f.chunk_size_bytes/1024 ),
            "chunk_mb": format!("{}MB", f.chunk_size_bytes/1048576 ),
            "upload_date": date_format_from_millis(f.upload_date.timestamp_millis()).unwrap_or_default()
        });
        Ok(Some(rs))
    }else{
        Ok(None)
    }
}
// 获取文件信息
pub async fn get_info_json(objectid:String, bucket_name:String) -> Result<Option<Value>, Json<Value>>{
    let conn = mdb::connect().await?;
    let options = GridFsBucketOptions::builder().bucket_name(bucket_name).build();
    let bucket = conn.gridfs_bucket(options);
    get_info_json_(mdb::to_object_id(objectid), bucket).await
}
// 获取文件目录与类型
pub async fn get_bucket_type(objectid:Bson, bucket:GridFsBucket) -> Result<Value, Json<Value>>{
    let doc = get_info_(objectid, bucket).await?;
    if let Some(f) = doc.metadata {
        if let Ok(bucket_name) = f.get_str("bucket"){
            if let Ok(filetype) = f.get_str("type"){
                Ok(json!({ "bucket": bucket_name, "type": filetype }))
            }else{
                Err(code::sys_("文件类型不存在"))
            }
        }else{
            Err(code::sys_("文件目录不存在"))
        }
    }else{
        Err(code::sys_("文件元信息不存在"))
    }
}
// pub async fn get_doc_op(objectid:String, bucket_name:String) -> Result<Option<FilesCollectionDocument>, Json<Value>>{
//     let conn = mdb::connect().await?;
//     let options = GridFsBucketOptions::builder().bucket_name(bucket_name).build();
//     let bucket = conn.gridfs_bucket(options);

//     get_file_op(mdb::to_object_id(objectid), bucket).await
// }
// pub async fn get_doc(id:String, bucket_name:String) -> Result<FilesCollectionDocument, Json<Value>>{
//     if let Some(f) = find_by_id_op(id.to_owned(), bucket_name).await? {
//         Ok(f)
//     }else{
//         Err(code::sys_(id + "文件未上传，请先上传文件！"))
//     }
// }

